function probFiles = pushMoraData(direc)
  % Ad hoc function--utilizing new ParseData-derived classes--to push "legacy"
  % moorings data into Mooring_COTS_Dev
  %
  % Author: David Goldsmith, Wash. State Dept. of Ecology, dgol461@ecy.wa.gov
  % Release date: N/A
  
    global conn
    DBFTM = struct(...% DB Table,          {DB Fields}}
                   'RawValue', {{'SiteID',...
                                 'ReportedDateDescription', 'ReportedTimeDescription', 'PostedUTCDatetime',...
                                 'SampleInterval', 'SIDataQualVal', 'SIDataQualFlag', 'SIDataQualCtrlLev',...
                                 'PressureQuantity', 'PresDataQualVal', 'PresDataQualFlag', 'PresDataQualCtrlLev',...
                                 'TemperatureQuantity', 'TempDataQualVal', 'TempDataQualFlag', 'TempDataQualCtrlLev',...
                                 'ConductivityQuantity','CondQAQC',...
                                 'SalinityQuantity', 'SalDataQualVal', 'SalDataQualFlag', 'SalDataQualCtrlLev',...
                                 'DensityQuantity', 'DenDataQualVal', 'DenDataQualFlag', 'DenDataQualCtrlLev',...
                                 'Aux0Quantity', 'Aux1Quantity', 'Aux2Quantity', 'Aux3Quantity',...
                                 'RealTimeFlagsID', 'ProcessedFlag'}},...
            'CalculatedValue', {{'MoraDO', 'MoraDOQAQC', 'a64DO', 'MoraDOSat',...
                                 'ChlCalculated', 'ChlQAQC', 'TurbCalculated', 'TurbQAQC'}}...
                  );
              
  % QAQC parameters
    SImin  = 7/720;   % 14 minutes in units of days
    SImax  = 1/90;    % 16 minutes in units of days
    ADMmin = 29/1440; % 29 minutes in units of days
    ADMmax = 31/1440; % 31 minutes in units of days
    
  % Main
    cd(direc);
    subdirecs = dir(direc); 
    subdirecs = {subdirecs.name};
    probFiles = {};
    conn = database('Mooring_COTS_Dev', '', '');
    set(conn, 'Autocommit', 'off')
    setdbprefs('NullNumberWrite', 'NaN')
    lastRVID = fetch(exec(conn, 'select max(RawValueID) from RawValue'));
    lastRVID = lastRVID.Data{1};
    for direc = subdirecs
        if ~ismember('.', direc{:})
            files = dir([pwd '\' direc{:}]);
            files = {files.name};
            for file = files
                file = file{:}
                if (length(file) > 4) && strcmp(file(end-3:end), '.txt')% && ~done1
                    p = ParseMooringsData([pwd '\' direc{:} '\' file]);
                    result = p.readDataFile;
                    if ischar(result)
                        probFiles{end+1} = result;
                    else
                      % Post-process results
                      % Correct DO field names
                        if any(ismember('DOCalculated', p.parsedData.fields))
                            p.parsedData.fields{find(strcmp(p.parsedData.fields,...
                                'DOCalculated'))} = 'MoraDO';
                        end
                        if any(ismember('DOSaturationCalculated', p.parsedData.fields))
                            p.parsedData.fields{find(strcmp(p.parsedData.fields,...
                                'DOSaturationCalculated'))} = 'MoraDOSat';
                        end
                      % Datetime stuff
                        p.parsedData.fields = extendArray(p.parsedData.fields,...
                                                         {'RealTimeFlagsID', 'PostedUTCDatetime',...
                                                          'SampleInterval', 'SIDataQualVal',...
                                                          'SIDataQualFlag', 'SIDataQualCtrlLev'},...
                                                          'c');
                        PUTCDTs = combineDateAndTime(p.parsedData.values{2}, p.parsedData.values{3});
                        N = length(PUTCDTs);
                        SI = diff(PUTCDTs);
                        PUTCDTs = cellstr(datestr(PUTCDTs', 'mm/dd/yyyy HH:MM:SS'));
                        zeroz = zeros(size(SI));
                        onez  = zeroz + 1;
                        SIDQV = 4 + zeroz;
                        SIDQF = onez;
                        SIDQC = [NaN; onez];
                        good  = (SI > SImin) & (SI < SImax);
                        if strfind(p.parsedData.values{1}{1}, 'ADM')
                            good = good | ((SI > ADMmin) & (SI < ADMmax));
                        end
                        bad = ~good;
                        if any(bad)
                            SIDQV(bad) = 1;
                            SIDQF(bad) = 6;
                        end
                      % Now prepend an NaN on the rest and add onto values field
                        SI = [NaN; SI]; SIDQV = [NaN; SIDQV]; SIDQF = [NaN; SIDQF];
                        p.parsedData.values = extendArray(p.parsedData.values,...
                                                         {[zeroz + (-9998); -9998],...
                                                          PUTCDTs,...
                                                          SI, SIDQV, SIDQF, SIDQC},...
                                                          'n');
                      % Look for QAQC CtrlLev values less than 2 (or missing)
                      % these need to be auto-QAQC-ed
                      % There were none: commenting out code that found them,
                      % not writing code to deal w/ them!
%                         CLcols = strfind(p.parsedData.fields, 'CtrlLev');
%                         CLcols = find(~cellfun('isempty', CLcols));
%                         for a=p.parsedData.values(CLcols)
%                             a = a{:};
%                             try
%                                 do = isnan(a) | (a < 2);
%                             catch ME
%                                 [p.dataFilename getReport(ME)]
%                             end
%                             if any(do)
%                                 p.dataFilename
%                                 find(do)
%                             end
%                         end
                      % Recatenate conductivity, DO, chlorophyl, and turbidity QAQC codes
                      % And change field names and values 
                        tmpCondCols = strfind(p.parsedData.fields, 'CondDataQual');
                        condCodeCols = find(~cellfun('isempty', tmpCondCols));
                        tmpDOCols = strfind(p.parsedData.fields, 'DO_CalcDataQual');
                        DOCodeCols = find(~cellfun('isempty', tmpDOCols));
                        tmpChlCols = strfind(p.parsedData.fields, 'ChlQAQC');
                        chlCodeCols = find(~cellfun('isempty', tmpChlCols));
                        tmpTurbCols = strfind(p.parsedData.fields, 'TurbQAQC');
                        turbCodeCols = find(~cellfun('isempty', tmpTurbCols));
                        A = intersect(find(cellfun('isempty', tmpCondCols)),...
                                      find(cellfun('isempty', tmpDOCols)));
                        B = intersect(find(cellfun('isempty', tmpChlCols)),...
                                      find(cellfun('isempty', tmpTurbCols)));
                        otherCols = intersect(A, B);
                        if ~isempty(condCodeCols)
                            tmpCondCodes = p.parsedData.values(condCodeCols);
                            condCodes = {};
                        end
                        if ~isempty(DOCodeCols)
                            tmpDOCodes = p.parsedData.values(DOCodeCols);
                            DOCodes = {};
                        end
                        if ~isempty(chlCodeCols)
                            tmpChlCodes = p.parsedData.values(chlCodeCols);
                            chlCodes = {};
                        end
                        if ~isempty(turbCodeCols)
                            tmpTurbCodes = p.parsedData.values(turbCodeCols);
                            turbCodes = {};
                        end
                        for i=1:N
                            if exist('condCodes', 'var')
                                if all(isnan([tmpCondCodes{1}(i) tmpCondCodes{2}(i) tmpCondCodes{3}(i)]))
                                    condCodes{end+1} = '';
                                else
                                    condCodes{end+1} = sprintf('%d_%d_%d',...
                                        [tmpCondCodes{1}(i) tmpCondCodes{2}(i) tmpCondCodes{3}(i)]);
                                end
                            end
                            if exist('DOCodes', 'var')
                                if all(isnan([tmpDOCodes{1}(i) tmpDOCodes{2}(i) tmpDOCodes{3}(i)]))
                                    DOCodes{end+1} = '';
                                else
                                    DOCodes{end+1} = sprintf('%d_%d_%d',...
                                        [tmpDOCodes{1}(i) tmpDOCodes{2}(i) tmpDOCodes{3}(i)]);
                                end
                            end
                            if exist('chlCodes', 'var')
                                if all(isnan([tmpChlCodes{1}(i) tmpChlCodes{2}(i) tmpChlCodes{3}(i)]))
                                    chlCodes{end+1} = '';
                                else
                                    chlCodes{end+1} = sprintf('%d_%d_%d',...
                                        [tmpChlCodes{1}(i) tmpChlCodes{2}(i) tmpChlCodes{3}(i)]);
                                end
                            end
                            if exist('turbCodes', 'var')
                                if all(isnan([tmpTurbCodes{1}(i) tmpTurbCodes{2}(i) tmpTurbCodes{3}(i)]))
                                    turbCodes{end+1} = '';
                                else
                                    turbCodes{end+1} = sprintf('%d_%d_%d',...
                                        [tmpTurbCodes{1}(i) tmpTurbCodes{2}(i) tmpTurbCodes{3}(i)]);
                                end
                            end
                        end
                        p.parsedData.fields = p.parsedData.fields(otherCols);
                        p.parsedData.values = p.parsedData.values(otherCols);
                        if exist('condCodes', 'var')
                            p.parsedData.fields{end+1} = 'CondQAQC';
                            p.parsedData.values{end+1} = condCodes;
                            clear condCodes
                        end
                        if exist('DOCodes', 'var')
                            p.parsedData.fields{end+1} = 'MoraDOQAQC';
                            p.parsedData.values{end+1} = DOCodes;
                            clear DOCodes
                        end
                        if exist('chlCodes', 'var')
                            p.parsedData.fields{end+1} = 'ChlQAQC';
                            p.parsedData.values{end+1} = chlCodes;
                            clear chlCodes
                        end
                        if exist('turbCodes', 'var')
                            p.parsedData.fields{end+1} = 'TurbQAQC';
                            p.parsedData.values{end+1} = turbCodes;
                            clear turbCodes
                        end
                      % Assemble RawValue insert query components
                        RawValueFields = {}; CalculatedValueFields = {};
                        RawValueValues = cell(N,1); j=1;
                        CalculatedValueValues = cell(N,1); k=1;
                        for i=1:length(p.parsedData.fields)
                            field = p.parsedData.fields{i};
                            value = p.parsedData.values{i};
                            if any(ismember(field, DBFTM.RawValue))
                                RawValueFields{end+1} = field;
                                try
                                    RawValueValues(:,j) = value;
                                catch
                                    RawValueValues(:,j) = mat2cell(value,ones(size(value)));
                                end
                                j = j + 1;
                            else
                                CalculatedValueFields{end+1} = field;
                                try
                                    CalculatedValueValues(:,k) = value;
                                catch
                                    CalculatedValueValues(:,k) = mat2cell(value,ones(size(value)));
                                end
                                k = k + 1;
                            end
                        end
                      % Begin database operations
                        try
                          % Submit RawValue table fastinsert query
                            fastinsert(conn, 'RawValue', RawValueFields, RawValueValues);
                          % Retrieve RawValueIDs just created
                            newRVIDs = fetch(exec(conn, ['select RawValueID from RawValue ' ...
                                                         'where RawValueID>' num2str(lastRVID)]));
                            newRVIDs = newRVIDs.Data;
                          % Construct cell array of "where clauses" for CalculatedValue table update query
                            where = cellstr(num2str([newRVIDs{:}]', 'where RawValueID=%d'));
                          % Submit CalculatedValue table query
                            if ~isempty(CalculatedValueFields)
                                update(conn, 'CalculatedValue', ...
                                              CalculatedValueFields, ...
                                              CalculatedValueValues, ...
                                              where);
                            end
                          % Confirm (weak)
                            curs = fetch(exec(conn, ['select count(*) '...
                                                     'from RawValue r inner join CalculatedValue c '...
                                                     'on r.RawValueID=c.RawValueID '...
                                                     'where r.RealTimeFlagsID=-9998 '...
                                                     'and c.RawValueID>' num2str(lastRVID)]));
                            numberAdded = curs.Data{:};
                            if numberAdded==length(RawValueValues(:,1))
                                commit(conn);
                                movefile([pwd '\' direc{:} '\' file], ...
                                         [pwd '\..\FromMoraComplete\' file]);
                                lastRVID = newRVIDs{end};
                            else
                                rollback(conn);
                                probFiles{end+1} = file;
                            end
                        catch me
                            getReport(me)
                            rollback(conn);
                        end
                        clear curs;
                    end
                end
            end
        end
    end
    try
        close(conn);
    catch
    end
end